package cn.t.utils;

import org.apache.commons.lang3.ObjectUtils;

import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjusters;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * @author l
 */
public class DateUtil {

    private DateUtil() {}

    public static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    public static final DateTimeFormatter DATE_FORMATTER_YMD = DateTimeFormatter.ofPattern("yyyy-MM-dd");

    public static Long getSecondByTime( LocalDateTime time,long second) {
        return time.plusSeconds(second).toEpochSecond(ZoneOffset.ofHours(8));
    }

    public static String getDateStr(Date date) {
        return date == null ? "" : date.toInstant().atZone(ZoneId.systemDefault()).format(DATE_FORMATTER);
    }

    public static String getDateStr(Date date, DateTimeFormatter formatter) {
        return date == null ? "" : date.toInstant().atZone(ZoneId.systemDefault()).format(formatter);
    }

    public static String getDateStr(LocalDateTime time, DateTimeFormatter formatter) {
        return time.format(formatter);
    }

    public static Date startDate(String dateStr) {
        if (ObjectUtils.isEmpty(dateStr)) {
            return null;
        }
        LocalDate dateDate = LocalDate.parse(dateStr, DATE_FORMATTER_YMD);
        LocalDateTime localDateTime = dateDate.atStartOfDay();
        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
        return Date.from(zonedDateTime.toInstant());
    }

    public static Date dateByStr(String dateStr) {
        LocalDateTime dateTime = LocalDateTime.parse(dateStr, DATE_FORMATTER);
        return Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    // 获取 afterVal(负数为之前的时间) 之后的时间
    public static Date afterTime(LocalDateTime dateTime, int afterVal, TimeUnit timeUnit) {
        switch (timeUnit) {
            case DAYS:
                return Date.from(dateTime.plusDays(afterVal).atZone(ZoneId.systemDefault()).toInstant());
            case HOURS:
                return Date.from(dateTime.plusHours(afterVal).atZone(ZoneId.systemDefault()).toInstant());
            case MINUTES:
                return Date.from(dateTime.plusMinutes(afterVal).atZone(ZoneId.systemDefault()).toInstant());
            case SECONDS:
                return Date.from(dateTime.plusSeconds(afterVal).atZone(ZoneId.systemDefault()).toInstant());
            default:
                return Date.from(dateTime.atZone(ZoneId.systemDefault()).toInstant());
        }
    }

    // 获取 afterVal(负数为之前的时间) 之后的时间
    public static Date afterMonth(LocalDateTime dateTime, int afterVal) {
        return Date.from(dateTime.plusMonths(afterVal).atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 获取时间差
     */
    public static long diffTime(Date startDate, Date endDate, TimeUnit timeUnit) {
        return timeUnit.convert(endDate.getTime() - startDate.getTime(), TimeUnit.MILLISECONDS);
    }

    public static Date closeDate(String dateStr,Long second) {
        LocalDateTime dateTime = LocalDateTime.parse(dateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        Long secondByTime = getSecondByTime(dateTime, second);
        return Date.from(LocalDateTime.ofInstant(Instant.ofEpochSecond(secondByTime), ZoneId.systemDefault()).atZone(ZoneId.systemDefault()).toInstant());
    }

    public static String setTime(Date time) {
        return time != null ? DateUtil.getDateStr(time) : "";
    }

    public static Date endDate(String dateStr) {
        if (ObjectUtils.isEmpty(dateStr)) {
            return null;
        }
        LocalDate dateTime = LocalDate.parse(dateStr, DATE_FORMATTER_YMD);
        LocalDateTime localDateTimeEndOfDay = LocalDateTime.of(dateTime.getYear(), dateTime.getMonthValue(), dateTime.getDayOfMonth(), 23, 59, 59);
        // 转换为Date对象
        return Date.from(localDateTimeEndOfDay.atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 每天零点
     */
    public static Date currentDaily() {
      return Date.from(LocalDateTime.now().withHour(0)
                .withMinute(0)
                .withSecond(0).withNano(0).atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 每周一零点
     */
    public static Date currentWeekly() {
        return Date.from(LocalDateTime.now().with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)).withHour(0)
                .withMinute(0)
                .withSecond(0).withNano(0).atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 每月零点
     */
    public  static Date currentMonthly() {
        return  Date.from(LocalDateTime.now().withDayOfMonth(1).withHour(0)
                .withMinute(0)
                .withSecond(0).withNano(0).atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 每半年零点
     */
    public static Date currentHalfYearly() {
        int month = LocalDateTime.now().getMonthValue();
        int halfYearMonth = (month <= 6) ? 1 : 7;
        return Date.from(LocalDateTime.now().withMonth(halfYearMonth).withDayOfMonth(1).withHour(0)
                .withMinute(0)
                .withSecond(0).withNano(0).atZone(ZoneId.systemDefault()).toInstant());
    }

    /**
     * 每年零点
     */
    public static Date currentYearly() {
        return Date.from(LocalDateTime.now().withDayOfYear(1).withHour(0)
                .withMinute(0)
                .withSecond(0).withNano(0).atZone(ZoneId.systemDefault()).toInstant());
    }
}
